package com.king.util;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.function.Consumer;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;

import com.king.event.ExceptionEvent;
import com.king.event.LoadingEvent;

import javafx.concurrent.Task;

/**
 * 异步数据处理
 * 
 * @author king
 * @date 2025年6月26日-15:22:35
 */
@Component
public class Async {

	/**
	 * 线程池
	 */
	private static ExecutorService service = Executors.newFixedThreadPool(2);

	@Autowired
	private ApplicationEventPublisher publisher;

	/**
	 * 处理方法
	 * 
	 * @param <T>
	 * @param call      异步线程要执行的业务逻辑方法
	 * @param onSuccess 异步线程执行完成后处理程序
	 * @author king
	 * @date 2025年6月26日-15:27:39
	 */
	public <T> void done(Callable<T> call, Consumer<T> onSuccess) {
		// 利用javafx的Task
		Task<T> task = new Task<T>() {
			@Override
			protected T call() throws Exception {
				// 可以处理一些业务逻辑前的东西，比如：校验是否有登录，如果没有登录，就不去获取数据了
				// 发布一个加载数据的事件
				publisher.publishEvent(LoadingEvent.LOADING);
				return call.call();
			}
		};
		service.execute(task);

		task.setOnSucceeded((_) -> {
			// 返回call中返回的内容
			try {
				onSuccess.accept(task.getValue());
			} catch (Throwable e) {
				publisher.publishEvent(ExceptionEvent.build(e));
			}
			// 当数据响应成功后，那么发布一个关闭模态的事件
			publisher.publishEvent(LoadingEvent.CLOSE);
		});

		task.setOnFailed((_) -> {
			publisher.publishEvent(ExceptionEvent.build(task.getException()));
			// 当数据响应成功后，那么发布一个关闭模态的事件
			publisher.publishEvent(LoadingEvent.CLOSE);
		});
	}

	public void shutdown() {
		service.shutdown();
	}

}
